package cultu.supplier.dao.jpa;

import javax.persistence.NoResultException;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cultu.core.message.JpqlParameter;
import cultu.framework.dao.jpa.GenericDAOjpa;
import cultu.supplier.dao.ProductDAO;
import cultu.supplier.message.Product;
import cultu.supplier.message.ProductCriteria;
import cultu.supplier.message.ProductList;
import cultu.supplier.message.ProductScenario;

/**
 * The Class ProductDAOjpa.
 */
public class ProductDAOjpa extends GenericDAOjpa<Product, ProductCriteria, ProductScenario> implements ProductDAO
{

  /** The Constant LOG. */
  private static final Log LOG = LogFactory.getLog(ProductDAOjpa.class);

  /**
   * @see cultu.framework.dao.BaseDAO#get(java.lang.Object, java.lang.Object)
   */
  public Product get(Product t, ProductScenario s)
  {
    Product result = null;

    if(t != null && t.getHjid() != null)
    {
      result = get(t.getHjid());
    }
    else
    {
      result = getByCustomKey(t.getCode());
    }

    if(result != null && s != null)
    {
      Product product = null;
      if(Boolean.TRUE.equals(s.getManageAnnotations()))
      {
        try
        {
          product = (Product) entityManager.createQuery("SELECT p FROM Product p LEFT JOIN FETCH p.annotations WHERE p.hjid=:hjid")
              .setParameter("hjid", result.getHjid())
              .getSingleResult();

          if(product != null)
          {
            result.setAnnotations(product.getAnnotations());
          }
        }
        catch(NoResultException nre)
        {
          LOG.info(nre.getMessage(), nre);
        }
      }

      if(Boolean.TRUE.equals(s.getManageCommunities()))
      {
        try
        {
          product = (Product) entityManager.createQuery("SELECT p FROM Product p LEFT JOIN FETCH p.communities WHERE p.hjid=:hjid")
              .setParameter("hjid", result.getHjid())
              .getSingleResult();

          if(product != null)
          {
            result.setCommunities(product.getCommunities());
          }
        }
        catch(NoResultException nre)
        {
          LOG.info(nre.getMessage(), nre);
        }
      }


      if(Boolean.TRUE.equals(s.getManageMedias()))
      {
        try
        {
          product = (Product) entityManager.createQuery("SELECT p FROM Product p LEFT JOIN FETCH p.medias WHERE p.hjid=:hjid")
              .setParameter("hjid", result.getHjid())
              .getSingleResult();

          if(product != null)
          {
            result.setMedias(product.getMedias());
          }
        }
        catch(NoResultException nre)
        {
          LOG.info(nre.getMessage(), nre);
        }
      } 
    }

    return result;
  }

  /**
   * Gets the by custom key.
   *
   * @param code the code
   * @return the by custom key
   */
  private Product getByCustomKey(String code)
  {
    Product result = null;

    if(code != null && !"".equals(code))
    {
      try
      {

        result = (Product) entityManager.createQuery("SELECT pdt FROM Produit pdt WHERE pdt.code=:code")
            .setParameter("code", code)
            .getSingleResult();
      }
      catch(NoResultException nre)
      {
        LOG.info(nre.getMessage(), nre);
      }
    }

    return result;
  }


  /**
   * @see cultu.framework.dao.jpa.GenericDAOjpa#update(cultu.core.message.BaseEntity)
   */
  @Override
  public Product update(Product p)
  {
    if(p != null && p.getHjid() == null)
    {
      try
      {
        Long id =(Long) entityManager.createQuery("SELECT p.hjid FROM Product p WHERE p.code = :code")
            .setParameter("code", p.getCode())
            .getSingleResult();
        p.setHjid(id);
      }
      catch(NoResultException nre)
      {
        LOG.info(nre.getMessage(), nre);
      }
    }
    return entityManager.merge(p);
  }

  /**
   * @see cultu.framework.dao.jpa.GenericDAOjpa#validateEntity(cultu.core.message.BaseEntity)
   */
  @Override
  protected boolean validateEntity(Product pEntity)
  {
    return pEntity != null && pEntity.getCode() != null && !"".equals(pEntity.getCode());
  }
  
  
  /**
   * {@inheritDoc}
   */
  public ProductList findNative(ProductCriteria pCriteria, ProductScenario pScenario) {
    
    // The product list.
    final ProductList productList = new ProductList();
    
    // Create query.
    final Query nativeQuery = entityManager.createNativeQuery(pCriteria.getJpqlQuery(), Product.class);
    
    // Give parameters if necessary.
    for (JpqlParameter parameter : pCriteria.getParameter()) {
      nativeQuery.setParameter(parameter.getAlias(), parameter.getValue());
    }
    
    // Add in collection.
    productList.getProducts().addAll(nativeQuery.getResultList());
    
    return productList;
  }
  
  /**
   * increaseBuytimes
   * @param productId
   */
  public void increaseBuytimes(final Long productId) {
    final String SQL = "UPDATE product SET buytimes = buytimes + 1 WHERE hjid = :productId";
    
    final Query query = entityManager.createNativeQuery(SQL);
    
    query.setParameter("productId", productId);
    
    query.executeUpdate();
  }
  
  /**
   * increaseConsultationtimes
   * @param productId
   */
  public void increaseConsultationtimes(final Long productId) {
    final String SQL = "UPDATE product SET consultationtimes = consultationtimes + 1 WHERE hjid = :productId";
    
    final Query query = entityManager.createNativeQuery(SQL);
    
    query.setParameter("productId", productId);
    
    query.executeUpdate();
  }
}
